package message;

import lombok.Data;
import lombok.EqualsAndHashCode;

/**
 * @author wb_zhulinzhong
 * @date 2021-04-14 16:44:46
 */
@EqualsAndHashCode(callSuper = true)
@Data
public abstract class Message extends JsonSerializable{

    private static final Integer TWO = 2;

    /**
     * 用户id
     */
    protected String uId;

    /**
     * 发给用户的id
     */
    protected String toUId;

    /**
     * 加密的16进制数据
     */
    protected String byteDataEncode;

    /**
     * 消息类型
     */
    protected Integer type;

    public Message(){
        setMediaType();
    }

    public Message(String uId, String toUId, byte[] data){
        this.uId = uId;
        this.toUId = toUId;
        this.byteDataEncode = bytesToHex(data);
        setMediaType();
    }

    /**
     * 强制子类制定自己的消息类型
     */
    protected abstract void setMediaType();

    /**
     * 获取消息中的数据
     * @return
     */
    public byte[] getData() {
        return hexToByteArray(this.byteDataEncode);
    }

    /**
     * 将字节数组转为16进制字符串
     * @param bytes
     * @return
     */
    private static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte aByte : bytes) {
            String hex = Integer.toHexString(aByte & 0xFF);
            if (hex.length() < TWO) {
                sb.append(0);
            }
            sb.append(hex);
        }
        return sb.toString();
    }

    /**
     * 16进制字符串转换为字节数组
     * @param inHex
     * @return
     */
    private static byte[] hexToByteArray(String inHex){
        int hexLen = inHex.length();
        byte[] result;
        if (hexLen % TWO == 1){
            //奇数
            hexLen++;
            result = new byte[(hexLen/2)];
            inHex="0"+inHex;
        }else {
            //偶数
            result = new byte[(hexLen/2)];
        }
        int j=0;
        for (int i = 0; i < hexLen; i+=TWO){
            result[j]=hexToByte(inHex.substring(i,i+2));
            j++;
        }
        return result;
    }

    /**
     * 16进制转化为字节
     * @param inHex
     * @return
     */
    private static byte hexToByte(String inHex){
        return (byte)Integer.parseInt(inHex,16);
    }
}
